package top.z.orm.handle.osql.core;

import top.z.orm.core.osql.exception.NoConfigException;
import top.z.orm.core.osql.transaction.Transaction;
import top.z.orm.handle.osql.constant.DbConfigConst;
import top.z.orm.handle.osql.transaction.JdbcTransaction;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public final class SessionFactory {

    private static BeeFactory beeFactory = null;

    private static boolean isFirst = true;

    /**
     * 无参构造函数
     */
    public SessionFactory() {
    }

    public static BeeFactory getBeeFactory() {
        if (beeFactory == null) {
            beeFactory = BeeFactory.getInstance();
        }
        return beeFactory;
    }

    public void setBeeFactory(BeeFactory beeFactory) {
        SessionFactory.beeFactory = beeFactory;
    }

    public static Transaction getTransaction() {
        Transaction transaction = getBeeFactory().getTransaction();
        if (null == transaction) {
            transaction = new JdbcTransaction();
        } else {
            transaction = getBeeFactory().getTransaction();
        }
        return transaction;
    }

    public static Connection getConnection() {
        Connection connection;
        try {
            DataSource ds = getBeeFactory().getDataSource();
            if (ds != null) {
                connection = ds.getConnection();
            } else {
                // do not set the dataSource
                connection = getOriginalConnection();
            }
        } catch (SQLException e) {
            throw ExceptionHelper.convert(e);
        } catch (ClassNotFoundException e) {
            Logger.error("Can not find the Database driver! " + e.getMessage());
            throw new NoConfigException("Can not find the Database driver(maybe miss the jar file)");
        } catch (Exception e) {
            Logger.error("Have Exception when getConnection: " + e.getMessage());
            throw ExceptionHelper.convert(e);
        }
        return connection;
    }

    private static Connection getOriginalConnection() throws ClassNotFoundException, SQLException {
        String driverName = HoneyConfig.getHoneyConfig().getDriverName();
        String url        = HoneyConfig.getHoneyConfig().getUrl();
        String username   = HoneyConfig.getHoneyConfig().getUsername();
        String password   = HoneyConfig.getHoneyConfig().getPassword();
        //
        String nullInfo = "";
        if (driverName == null) nullInfo += DbConfigConst.DB_DRIVERNAME + " do not config; ";
        if (url == null) nullInfo += DbConfigConst.DB_URL + " do not config; ";
        if (username == null) nullInfo += DbConfigConst.DB_USERNAM + " do not config; ";
        if (password == null) nullInfo += DbConfigConst.DB_PWORD + " do not config; ";
        //
        if (!"".equals(nullInfo)) {
            // throw new NoConfigException("NoConfigException,Do not set the database info: " + nullInfo);
            if (isFirst) {
                Logger.warn("Do not set the database info: " + nullInfo);
                isFirst = false;
            }
        }
        Connection connection;
        if (driverName != null && !"".equals(driverName.trim())) {
            // some db,no need set the driverName
            Class.forName(driverName);
        }
        if (username != null && !"".equals(username.trim()) && password != null) {
            connection = DriverManager.getConnection(url, username, password);
        } else {
            connection = DriverManager.getConnection(url);
        }
        return connection;
    }
}